package com.lej.home.pay

import android.text.SpannableStringBuilder
import android.text.method.LinkMovementMethod
import androidx.core.view.isVisible
import androidx.core.widget.doAfterTextChanged
import com.alibaba.android.arouter.facade.annotation.Route
import com.lej.core.base.BaseFragment
import com.lej.core.common.IS_ORDER_DETAIL
import com.lej.core.common.IS_ORDER_PAY_DETAIL
import com.lej.core.common.ORDER_DETAIL_ID
import com.lej.core.common.PAY_DETAIL_ID
import com.lej.core.dsl.stateEnableTextColor
import com.lej.core.router.CRouter
import com.lej.core.utils.extention.*
import com.lej.core.utils.load
import com.lej.core.widget.drawable.CustomDrawable
import com.lej.core.widget.drawable.getStateDrawable
import com.lej.dataservice.club.bean.main.home.PayDetailInfo
import com.lej.dataservice.club.bean.main.home.WxPayInfo
import com.lej.dataservice.club.http.base.HttpUrl
import com.lej.dataservice.club.http.bean.onError
import com.lej.dataservice.club.http.bean.onSuccess
import com.lej.home.BR
import com.lej.home.R
import com.lej.home.databinding.HomeFragmentNftPayBinding
import com.lej.pay.utils.PayUtils
import com.lej.wx.data.WxStatus
import com.qmuiteam.qmui.kotlin.onClick
import kotlin.math.min

/**
 *  author: cjq
 *  date  : 2022/7/18 0018
 *  desc  :
 */
@Route(path = CRouter.nftPayDetail)
class NftPayFragment : BaseFragment<HomeFragmentNftPayBinding, NftPayVM>() {
    private var isBuy = false // true 购买  false 求购
    private var buyNum = 1
    override fun getLayout(): Int = R.layout.home_fragment_nft_pay

    override fun initVariableId(): Int = BR.vm

    override fun initData() {
        super.initData()
        isBuy = arguments?.getBoolean(IS_ORDER_PAY_DETAIL) == false
        viewModel.nftId = arguments?.getInt(PAY_DETAIL_ID, -1) ?: -1
        binding.ivInputClose.onClick {
            removeFragment()
        }
        getDetailData()
    }

    private fun setDetailData(info: PayDetailInfo) {
        setBtnState(info)
        val selDrawable =
            CustomDrawable(strokeWidth = 1, strokeColor = R.color.textStressColor, cornerRadius = 5)
        if (isBuy) {
            binding.tvBuyNum.background = selDrawable
            binding.tvReduceNum.stateEnableTextColor(
                R.color.textHintColor.resColor,
                R.color.textNormalColor.resColor
            )
            binding.tvAddNum.stateEnableTextColor(
                R.color.textHintColor.resColor,
                R.color.textNormalColor.resColor
            )
            binding.tvAddNum.onClick {
                buyNum += 1
                setBtnState(info)
            }
            binding.tvReduceNum.onClick {
                buyNum -= 1
                setBtnState(info)
            }
            info.per_user_limit?.let { binding.tvLimit.text = if (it == 0) "" else "限购数量·${it}版" }
        } else {
            binding.etNum.background = selDrawable
            binding.etNum.doAfterTextChanged {
                if (it.isNullOrEmpty()) binding.etNum.setText("1")
                val addNum = binding.etNum.text.toString().toInt() * 100
                info.price?.let { itt ->
                    binding.tvPrice.text = "¥ ${(itt + addNum).toDouble() / 100}"
                }
            }
        }
        binding.tvAddTips.text = if (isBuy) "购买数量" else "试试加价向其他用户求购吧"
        binding.groupBuy.isVisible = isBuy
        binding.groupWant.isVisible = !isBuy
        val grayDrawable = CustomDrawable(cornerRadius = 100, solidColor = R.color.themeGrayColor)
        binding.tvPay.background =
            getStateDrawable(
                grayDrawable,
                null,
                null,
                context?.getDrawableCompat(R.drawable.ic_btn_pay_confirm)
            )
        binding.cbAgreement.setOnCheckedChangeListener { _, isChecked ->
            binding.tvPay.isEnabled = isChecked
        }

        binding.cbAgreement.let {
            it.movementMethod = LinkMovementMethod.getInstance()
            it.text = SpannableStringBuilder("我已阅读并同意")
                .append("《大有宝藏数字藏品购买协议》".textLinkClick {
                    activity?.toLink(HttpUrl.TRANSFORM_PROTOCOL_URL)
                })
        }
        load(
            info.cover,
            R.drawable.ic_load_place,
            R.drawable.ic_load_place_error,
            binding.iv
        )
        binding.tvTitle.text = info.name
        binding.tvStyle.text = "数字文创·${info.getNftType()}"
        binding.tvAuthor.text = "创作者·${info.author}"
        info.price?.let { itt ->
            val price = if (isBuy) itt.toDouble() / 100 else (itt + 100).toDouble() / 100
            binding.tvPrice.text = "¥ $price"
        }
        binding.tvPay.onClick {
            if (isBuy) {
                createBuyOrder(info.pay_info_id ?: 0, binding.tvBuyNum.text.toString().toInt())
            } else {
                createOrder(
                    info.pay_info_id ?: 0,
                    info.price ?: 0,
                    binding.etNum.text.toString().toInt() * 100
                )
            }
        }
    }

    private fun removeFragment() {
        kotlin.runCatching {
            activity?.supportFragmentManager?.beginTransaction()?.remove(this)?.commit()
        }
    }

    /**
     * 创建订单
     */
    private fun getDetailData() {
        showLoading()
        viewModel.getPayDetail().onSuccess(this) {
            hideLoading()
            if (it.pay_info_id == null || it.price == null) {
                "订单创建失败".toast()
                return@onSuccess
            }
            setDetailData(it)
        }.onError(this) {
            hideLoading()
            it.message.toast()
        }
    }

    private fun setBtnState(info: PayDetailInfo) {
        binding.tvBuyNum.text = buyNum.toString()
        info.price?.let { binding.tvPrice.text = "¥${(it * buyNum).toDouble() / 100}" }
        binding.tvReduceNum.isEnabled = buyNum > 1
        val limitNum = if (info.isLimit()) {
            min(info.per_user_limit_current ?: 0, info.stock ?: 0)
        } else info.stock
        binding.tvAddNum.isEnabled = buyNum < limitNum ?: 0
    }

    /**
     * 创建购买订单
     */
    private fun createBuyOrder(payInfoId: Int, num: Int) {
        showLoading()
        viewModel.createBuyOrder(payInfoId, num).onSuccess(this) { itt ->
            val orderId = itt.get("order_id").asInt
            buyPay(orderId)
        }.onError(this) {
            hideLoading()
            it.message.toast()
        }
    }

    /**
     * 创建求购订单
     */
    private fun createOrder(payId: Int, price: Int, addPrice: Int) {
        showLoading()
        viewModel.createOrder(payId, price, addPrice).onSuccess(this) { itt ->
            val orderId = itt.get("order_id").asInt
            orderPay(orderId)
        }.onError(this) {
            hideLoading()
            it.message.toast()
        }
    }

    /**
     * 求购订单支付
     */
    private fun orderPay(orderId: Int) {
        viewModel.orderPay(orderId).onSuccess(this) { itt ->
            hideLoading()
            wxPay(itt, orderId, true)
        }.onError(this) {
            hideLoading()
            it.message.toast()
        }
    }

    /**
     * 购买订单支付
     */
    private fun buyPay(orderId: Int) {
        viewModel.buyPay(orderId).onSuccess(this) { itt ->
            hideLoading()
            wxPay(itt, orderId, false)
        }.onError(this) {
            hideLoading()
            it.message.toast()
        }
    }

    private fun wxPay(info: WxPayInfo, orderId: Int, isOrderBuy: Boolean) {//调起支付
        if (context == null) return
        PayUtils.wxPay(
            context = requireContext(),
            appId = info.appId,
            partnerId = info.partnerid,
            prepayId = info.prepayid,
            noncestr = info.nonceStr,
            timestamp = info.timeStamp,
            paySign = info.paySign
        ) { status, msg ->
            when (status) {
                WxStatus.WX_OK -> {
                    "支付成功".toast()
                    router(CRouter.nftPayResultDetail) {
                        withBoolean(IS_ORDER_DETAIL, isOrderBuy)
                        withInt(ORDER_DETAIL_ID, orderId)
                    }
                    removeFragment()
                }
                WxStatus.WX_CANCEL -> "取消支付".toast()
                WxStatus.WX_ERROR -> "支付失败".toast()
            }
        }
    }
}